package Operators;

import java.util.ArrayList;
import States.CMState;
import Templates.Operator;

public class CMOperators {	
	
private static ArrayList<Operator<CMState>> CMOperators=new ArrayList<Operator<CMState>>();
	
	public static ArrayList<Operator<CMState>> returnOperators()
	{

		CMOperators.add(new Move1CanibalLeft());
		CMOperators.add(new Move1CanibalRight());
		CMOperators.add(new Move1MissionaryLeft());
		CMOperators.add(new Move1MissionaryRight());
		CMOperators.add(new Move1Missionary1CanibalLeft());
		CMOperators.add(new Move1Missionary1CanibalRight());
		CMOperators.add(new Move2MissionaryLeft());
		CMOperators.add(new Move2MissionaryRight());
		CMOperators.add(new Move2CanibalLeft());
		CMOperators.add(new Move2CanibalRight());

		return CMOperators;
	}
	
	public static class InitialState implements Operator<CMState>
	{
		public String toString(){
	
		return "Initial State";
	}
		
		public int getOperatorNumber()
		{
			return 0;
		}		
	
	public CMState execute(CMState s)
	{
		return null;
	}
	
	public boolean available(CMState s)
	{
		return false;
		
	}
	}
	
	public static class Move1CanibalLeft implements Operator<CMState>
	{
		public String toString(){
	
		return "Move 1 Canibal Left";
	}
		
		public int getOperatorNumber()
		{
			return 1;
		}		
	
	public CMState execute(CMState s)
	{
		CMState s2=new CMState(s);
		s2.setLeftCanibals(s2.getLeftCanibals()+1);
		s2.setRightCanibals(s2.getRightCanibals()-1);
		s2.setBoat("left");
		return s2;
	}
	
	public boolean available(CMState s)
	{
		if(s.getBoat().equals("right"))
		if (s.getRightCanibals()>=1)
			if((s.getLeftCanibals()+1<=s.getLeftMissionaries()) || (s.getLeftMissionaries()==0))
				return true;
		return false;
	}
	}
	public static class Move1CanibalRight implements Operator<CMState>
	{
		public String toString(){
	
		return "Move 1 Canibal Right";
	}
		
		public int getOperatorNumber()
		{
			return 2;
		}		
	
	public CMState execute(CMState s)
	{
		CMState s2=new CMState(s);
		s2.setLeftCanibals(s2.getLeftCanibals()-1);
		s2.setRightCanibals(s2.getRightCanibals()+1);
		s2.setBoat("right");
		return s2;
	}
	
	public boolean available(CMState s)
	{
		if(s.getBoat().equals("left"))
		if (s.getLeftCanibals()>=1)
			if((s.getRightCanibals()+1<=s.getRightMissionaries()) || (s.getRightMissionaries()==0))
				return true;
		return false;
	}
	}
	public static class Move2CanibalLeft implements Operator<CMState>
	{
		public String toString(){
	
		return "Move 2 Canibal Left";
	}
		
		public int getOperatorNumber()
		{
			return 3;
		}		
	
	public CMState execute(CMState s)
	{
		CMState s2=new CMState(s);
		s2.setLeftCanibals(s2.getLeftCanibals()+2);
		s2.setRightCanibals(s2.getRightCanibals()-2);
		s2.setBoat("left");
		return s2;
	}
	
	public boolean available(CMState s)
	{
		if(s.getBoat().equals("right"))
		if (s.getRightCanibals()>=2)
			if((s.getLeftCanibals()+2<=s.getLeftMissionaries()) || (s.getLeftMissionaries()==0))
				return true;
		return false;
	}
	}
	public static class Move2CanibalRight implements Operator<CMState>
	{
		public String toString(){
	
		return "Move 2 Canibal Right";
	}
		
		public int getOperatorNumber()
		{
			return 4;
		}		
	
	public CMState execute(CMState s)
	{
		CMState s2=new CMState(s);
		s2.setLeftCanibals(s2.getLeftCanibals()-2);
		s2.setRightCanibals(s2.getRightCanibals()+2);
		s2.setBoat("right");
		return s2;
	}
	
	public boolean available(CMState s)
	{
		if(s.getBoat().equals("left"))
		if (s.getLeftCanibals()>=2)
			if((s.getRightCanibals()+2<=s.getRightMissionaries()) || (s.getRightMissionaries()==0))
				return true;
		return false;
	}
	}
	public static class Move1MissionaryLeft implements Operator<CMState>
	{
		public String toString(){
	
		return "Move 1 Missionary Left";
	}
		
		public int getOperatorNumber()
		{
			return 5;
		}		
	
	public CMState execute(CMState s)
	{
		CMState s2=new CMState(s);
		s2.setLeftMissionaries(s2.getLeftMissionaries()+1);
		s2.setRightMissionaries(s2.getRightMissionaries()-1);
		s2.setBoat("left");
		return s2;
	}
	
	public boolean available(CMState s)
	{
		if(s.getBoat().equals("right"))
		if (s.getRightMissionaries()>=1)
			if((s.getRightMissionaries()-1>=s.getRightCanibals())  || (s.getRightMissionaries()-1==0))
				if(s.getLeftMissionaries()+1>=s.getLeftCanibals())
				return true;
		return false;
	}
	}
	public static class Move1MissionaryRight implements Operator<CMState>
	{
		public String toString(){
	
		return "Move 1 Missionary Right";
	}
		
		public int getOperatorNumber()
		{
			return 6;
		}		
	
	public CMState execute(CMState s)
	{
		CMState s2=new CMState(s);
		s2.setLeftMissionaries(s2.getLeftMissionaries()-1);
		s2.setRightMissionaries(s2.getRightMissionaries()+1);
		s2.setBoat("right");
		return s2;
	}
	
	public boolean available(CMState s)
	{
		if(s.getBoat().equals("left"))
		if (s.getLeftMissionaries()>=1)
			if((s.getLeftMissionaries()-1>=s.getLeftCanibals()) || (s.getLeftMissionaries()-1==0))
				if(s.getRightMissionaries()+1>=s.getRightCanibals())
				return true;
		return false;
	}
	}
	public static class Move2MissionaryLeft implements Operator<CMState>
	{
		public String toString(){
	
		return "Move 2 Missionary Left";
	}
		
		public int getOperatorNumber()
		{
			return 7;
		}		
	
	public CMState execute(CMState s)
	{
		CMState s2=new CMState(s);
		s2.setLeftMissionaries(s2.getLeftMissionaries()+2);
		s2.setRightMissionaries(s2.getRightMissionaries()-2);
		s2.setBoat("left");
		return s2;
	}
	
	public boolean available(CMState s)
	{
		if(s.getBoat().equals("right"))
		if (s.getRightMissionaries()>=2)
			if((s.getRightMissionaries()-2>=s.getRightCanibals()) || s.getRightMissionaries()-2==0)
				if(s.getLeftMissionaries()+2>=s.getLeftCanibals())
				return true;
		return false;
	}
	}
	public static class Move2MissionaryRight implements Operator<CMState>
	{
		public String toString(){
	
		return "Move 2 Missionary Right";
	}
		
		public int getOperatorNumber()
		{
			return 8;
		}		
	
	public CMState execute(CMState s)
	{
		CMState s2=new CMState(s);
		s2.setLeftMissionaries(s2.getLeftMissionaries()-2);
		s2.setRightMissionaries(s2.getRightMissionaries()+2);
		s2.setBoat("right");
		return s2;
	}
	
	public boolean available(CMState s)
	{
		if(s.getBoat().equals("left"))
		if (s.getLeftMissionaries()>=2)
			if((s.getLeftMissionaries()-2>=s.getLeftCanibals()) || (s.getLeftMissionaries()-2==0))
				if(s.getRightMissionaries()+2>=s.getRightCanibals())
				return true;
		return false;
	}
	}
	public static class Move1Missionary1CanibalRight implements Operator<CMState>
	{
		public String toString(){
	
		return "Move 1 Missionary 1 Canibal Right";
	}
		
		public int getOperatorNumber()
		{
			return 9;
		}		
	
	public CMState execute(CMState s)
	{
		CMState s2=new CMState(s);
		s2.setLeftMissionaries(s2.getLeftMissionaries()-1);
		s2.setRightMissionaries(s2.getRightMissionaries()+1);
		s2.setLeftCanibals(s2.getLeftCanibals()-1);
		s2.setRightCanibals(s2.getRightCanibals()+1);
		s2.setBoat("right");
		return s2;
	}
	
	public boolean available(CMState s)
	{
		if(s.getBoat().equals("left"))
		if (s.getLeftMissionaries()>=1 && s.getLeftCanibals()>=1)
			if(s.getLeftMissionaries()-1>=s.getLeftCanibals()-1)
				if(s.getRightMissionaries()+1>=s.getRightCanibals()+1)
				return true;
		return false;
	}
	}
	public static class Move1Missionary1CanibalLeft implements Operator<CMState>
	{
		public String toString(){
	
		return "Move 1 Missionary 1 Canibal Left";
	}
		
		public int getOperatorNumber()
		{
			return 10;
		}		
	
	public CMState execute(CMState s)
	{
		CMState s2=new CMState(s);
		s2.setLeftMissionaries(s2.getLeftMissionaries()+1);
		s2.setRightMissionaries(s2.getRightMissionaries()-1);
		s2.setLeftCanibals(s2.getLeftCanibals()+1);
		s2.setRightCanibals(s2.getRightCanibals()-1);
		s2.setBoat("left");
		return s2;
	}
	
	public boolean available(CMState s)
	{
		if(s.getBoat().equals("right"))
		if (s.getLeftMissionaries()>=1 && s.getRightCanibals()>=1)
			if(s.getLeftMissionaries()-1>=s.getLeftCanibals()-1)
				if(s.getRightMissionaries()+1>=s.getRightCanibals()+1)
				return true;
		return false;
	}
	}
	

}
